import unittest
import datetime
import uuid
import json

from Autotests.Cloud.Clients import FinancialService
from Autotests.Cloud.executor import ActionExecutor
from Autotests.BaseTest import BaseTestCase


class PartnerBillingTest(BaseTestCase):
    def test_PartnerBilling(self):
        executor = ActionExecutor()
        finserv = FinancialService()
        testPartnerName = 'test-' + str(uuid.uuid4())
        invoicerId = None
        partnerId = executor.addPartner(parentInfo = executor.getPartnerInfo('IASO'),
                                        name = testPartnerName,
                                        level = 'Distributor',
                                        inheritFromParent = True)

        def AddPrice():
            currency = 'EUR'
            billingMethod = 'FixedPrice'
            priceData = {
                'sizeLimit' : 2,
                'priceBelowLimit' : 5.0,
                'priceAboveLimit' : 10.0
            }
            r = finserv.createObject('AddPriceRequest')
            r.priceInfo.descriptor.currency = currency
            r.priceInfo.billingMethod = billingMethod
            r.priceInfo.priceData = json.dumps(priceData)
            addPriceResult = finserv.call('AddPrice', r)
            return addPriceResult.key.entityId, billingMethod

        def AddInvoicer():
            result = finserv.call('EnumerateInvoiceNumberSequences')
    
            if len(result.item) == 0:
                self.fail('EnumerateInvoiceNumberSequences returned empty list')
                return False

            invoiceNumberSequenceId = result.item[0].id
    
            r = finserv.createObject('AddInvoicerRequest')
            r.invoicerInfo.name = 'test-' + str(uuid.uuid4())
            r.invoicerInfo.invoiceNumberSequenceId = invoiceNumberSequenceId
            invoicerId = finserv.call('AddInvoicer', r)
    
            return True

        def TestPartnerBillingInfo(priceEntityId, billingMethod):
            serverCount = 5
            workstationCount = 10
            usedStorage = '1'
            selectedSize = '2'
            minimalBillAmount = '3'
    
            r = finserv.createObject('SetPartnerBillingInfoRequest')
            r.billingInfo.partnerId = partnerId
            r.billingInfo.serverCount = serverCount
            r.billingInfo.workstationCount = workstationCount
            r.billingInfo.usedStorage = usedStorage
            r.billingInfo.selectedSize = selectedSize
            r.billingInfo.billingMethod = billingMethod
            r.billingInfo.priceEntityId = priceEntityId
            r.billingInfo.minimalBillAmount = minimalBillAmount
            r.billingInfo.invoicerId = invoicerId
            r.billingInfo.partnerWeight = 'Undefined'
            r.billingInfo.partnerPrivilege = 'Undefined'
    
            finserv.call('SetPartnerBillingInfo', r)
    
            request = finserv.createObject('GetPartnerBillingInfoRequest')
            request.partnerId = partnerId
    
            updatedBillInfo = finserv.call('GetPartnerBillingInfo', request).partnerBillingInfo

            self.assertEqual(updatedBillInfo.serverCount, serverCount)
            self.assertEqual(updatedBillInfo.workstationCount, workstationCount)
            self.assertEqual(updatedBillInfo.usedStorage, usedStorage)
            self.assertEqual(updatedBillInfo.selectedSize, selectedSize)
            self.assertEqual(updatedBillInfo.minimalBillAmount, minimalBillAmount)
            self.assertEqual(updatedBillInfo.priceEntityId, int(priceEntityId))
            self.assertEqual(updatedBillInfo.billingMethod, billingMethod)

        def TestPartnerTargetCosts():
            r = finserv.createObject('AddPartnerTargetCostRequest')
            r.partnerTargetCost.id = 1
            r.partnerTargetCost.partnerId = partnerId
            r.partnerTargetCost.period.startTime = datetime.datetime.utcnow().isoformat()
            r.partnerTargetCost.period.endTime = (datetime.datetime.utcnow() + datetime.timedelta(30)).isoformat()
            r.partnerTargetCost.startCost = 0
            r.partnerTargetCost.startCostCurrency = 'EUR'
            r.partnerTargetCost.endCost = 1000
            r.partnerTargetCost.endCostCurrency = 'EUR'
    
            partnerTargetCostId = finserv.call('AddPartnerTargetCost', r)
    
            request = finserv.createObject('EnumeratePartnerTargetCostsRequest')
            request.partnerId = partnerId
            result = finserv.call('EnumeratePartnerTargetCosts', request)
    
            self.assertEqual(len(result.item), 1)
    
            partnerTargetCostInfo = result.item[0]
    
            self.assertEqual(r.partnerTargetCost.startCost, int(partnerTargetCostInfo.startCost))
            self.assertEqual(r.partnerTargetCost.startCostCurrency, partnerTargetCostInfo.startCostCurrency)
            self.assertEqual(r.partnerTargetCost.endCost, int(partnerTargetCostInfo.endCost))
            self.assertEqual(r.partnerTargetCost.endCostCurrency, partnerTargetCostInfo.endCostCurrency)
    
            request = finserv.createObject('EnumeratePartnerTargetCostsAtTimeRequest')
            request.partnerId = partnerId
            request.timestamp = datetime.datetime.utcnow().isoformat()
            finserv.call('EnumeratePartnerTargetCostsAtTime', request)
    
            self.assertEqual(len(result.item), 1)
    
            r = finserv.createObject('RemovePartnerTargetCostRequest')
            r.partnerTargetCostId = partnerTargetCostId
            finserv.call('RemovePartnerTargetCost', r)

        try:
            if not AddInvoicer():
                return
            priceEntityId, billingMethod = AddPrice()
            TestPartnerBillingInfo(priceEntityId, billingMethod)
            TestPartnerTargetCosts()
        finally:
            #executor.removePartner(self._testPartnerName, True)
            if invoicerId != None:
                r = finserv.createObject('RemoveInvoicerRequest')
                r.id = invoicerId
                finserv.call('RemoveInvoicer', r)

if __name__ == "__main__":
    unittest.main()
